﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace calendar
{

//日期范围类, 表示一个时间段, 由开始日期和结束日期组成.


public class DateRange : IComparable<DateRange>
{
    private DateTime m_start;
    private DateTime m_end;

    public static readonly DateRange EMPTY_RANGE = new DateRange();

    public DateRange()
    {
        m_start = new DateTime(0);
        m_end = m_start;
    }

    public DateRange(DateTime startDate, DateTime endDate)
    {
        m_start = startDate;
        m_end = endDate;
    }

    public DateTime Start
    {
        get {
            return m_start;
        } set {
            m_start = value;
        }
    }

    public DateTime End
    {
        get {
            return m_end;
        } set {
            m_end = value;
        }
    }

    public long InRangeOfTicks(long ticks)
    {
        long res = 0;
        DateTime temp_date = new DateTime(ticks);
        if (m_start.Year == 1 && m_start.Month == 1 && m_start.Day == 1) {
            ticks = ticks - temp_date.Date.Ticks;
        }
        if (ticks < m_start.Ticks) {
            res = 0;
        } else if (ticks > m_end.Ticks) {
            res = m_end.Ticks - m_start.Ticks;
        } else {
            res = ticks - m_start.Ticks;
        }
        return res;
    }


    //新增 IROT， 返回 DateRange 在另一个 DateRange 中的 ticks
    public long InRangeOfTicks(DateTime start, DateTime end)
    {
        long res = 0;
        long t = 0;

        DateTime DRStart = start.Date;
        DateTime DREnd = DRStart.Date;

        DRStart = DRStart.AddTicks( m_start.TimeOfDay.Ticks );
        DREnd = DREnd.AddTicks(m_end.TimeOfDay.Ticks);


        if (start > DREnd || end < DRStart) {
            return res;
        }

        if (start > DRStart) {
            t = start.TimeOfDay.Ticks;
        } else {
            t = DRStart.TimeOfDay.Ticks;
        }

        if (end > DREnd) {
            res = DREnd.TimeOfDay.Ticks - t;
        } else {
            res = end.TimeOfDay.Ticks - t;
        }
        return res;
    }

    //public int CompareTo(DateTime date)
    //{
    //    int result = DateTime.Compare(m_start, date);
    //    if (result == 0) {
    //        result = DateTime.Compare(m_end, date);
    //    }
    //    return result;
    //}

    //public int CompareTo(DateRange daterange)
    //{
    //    int result = DateTime.Compare(m_start, daterange.m_start);
    //    if (result == 0) {
    //        result = DateTime.Compare(m_end, daterange.m_end);
    //    }
    //    return result;
    //}

    public int CompareTo(DateTime date)
    {
        return DateUtility.compare(m_start, m_end, date);   
    }

    public int CompareTo(DateRange other)
    {
        int result = DateUtility.compare(m_start, other.Start);
        if (result == 0)
        {
            result = DateUtility.compare(m_end, other.End);
        }
        return result;
    }

    public override bool Equals(object obj)
    {
        bool result = false;
        if (obj is DateRange)
        {
            DateRange rhs = (DateRange)obj;
            result = (CompareTo(rhs) == 0);
        }
        return result;
    }

    public override int GetHashCode()
    {
        long start = m_start.Ticks;
        long end = m_end.Ticks;
        int result = ((int)start ^ (int)(start >> 32)) ^ ((int)end ^ (int)(end >> 32));
        return result;
    }
    public long TotalTicks
    {
        get {
            return (m_end.TimeOfDay.Ticks - m_start.TimeOfDay.Ticks);
        }
    }

    public override string ToString()
    {
        return ("[DateRange start = " + m_start + " end = " + m_end + " ]");
    }    
}
}
